import Config
import math
'''
Created on 2015年12月11日

@author: SunXiaohui
'''

# 将读取的数据包装成List或其他数据结构
def initialSimilarity(itemA, itemB):
    packA = []
    packB = []
    for x in itemA:
        if(itemA[x] !=0 and itemB[x] != 0):
            packA.append(int(itemA[x]))
            packB.append(int(itemB[x]))

# 计算两个用户的相似度
def computeSimilarity(itemA, itemB, initialFunc):
    initialFunc(itemA,itemB)
    ItemSum = itemA.length
    sumPreA = sumPreB = sumSquareA = sumSquareB = sumResult = 0
    for x in range(ItemSum):
        sumPreA += itemA[x]
        sumPreB += itemB[x]
        sumSquareA += itemA[x] ** 2
        sumSquareB += itemB[x] ** 2
        sumResult += sumPreA[x] * sumPreB[x]
    sumTmp = ItemSum * sumResult - sumPreA * sumPreB
    tmp = ItemSum *sumSquareA - sumSquareA ** 2 * (ItemSum * sumSquareA - sumSquareB ** 2)
    result = math.sqrt(tmp)
    if(result == 0):
        return result
    result = sumTmp / result
    return result

#  相似度矩阵，训练集
def genSimilarityMatrix(preference):
    matrix = []
    for x in range(Config.PREFROWCOUNT):
        for y in range(Config.PREFROWCOUNT):
            if(x == y):
                matrix[x][y] = 1
            else:
                matrix[x][y] = computeSimilarity(preference[x], preference[y], initialSimilarity)
    return matrix  

# 求相似度高的用户
def findNeighbors(score, item, similarityMatrix):
    similarity = []
    neighbors = []
    for x in range(similarityMatrix.length):
        if(score[x] != 0):
            similarity[x] = similarityMatrix[x][item]
        else:
            similarity[x] = 0    
    similaritySorted = similarity[:]
    similaritySorted.sort()
    for x in range(similarity.length):
        for y  in range(similaritySorted.length - 1, similaritySorted.length - Config.NEIGHBOUR_NUM,  -1):
            if(similarity[x] == similaritySorted[y] and similarity[x] != 0):
                neighbors.append(x)                
    return neighbors

# 计算均方根误差
def computeRSME(matrix, test):
    RSME = 0
    resMatrix = []
    for x in range(Config.TESTROWCOUNT):
        sumValue = 0
        n = 0
        for y in range(Config.PREFROWCOUNT):
            if(test[x][y] != 0 and matrix[x][y] != 0):
                sum += (matrix[x][y] - test[x][y]) ** 2
                n += 1
        if(n != 0):          
            RSME = math.sqrt(sumValue / n)
        resMatrix[x] = RSME
    return resMatrix
        
    


    